import {Plugin} from "@ckeditor/ckeditor5-core";
import {toWidget} from "@ckeditor/ckeditor5-widget";
import FileRepository from "@ckeditor/ckeditor5-upload/src/filerepository";
import UploadVideoCommand from "./uploadvideocommand";

export default class UploadVideoEditing extends Plugin {
    /**
     * @inheritDoc
     */
    static get requires() {
        return [FileRepository];
    }

    /**
     * @inheritDoc
     */
    static get pluginName() {
        return 'UploadVideoEditing';
    }

    /**
     * @inheritDoc
     */
    init() {
        const editor = this.editor;

        // Register `uploadImage` command
        editor.commands.add('insertVideo', new UploadVideoCommand(editor));

        editor.model.schema.register('videoBlock', {
            inheritAllFrom: '$blockObject',
            allowAttributes: ['src', 'style', 'width', 'height', 'controls']
        });

        editor.conversion.for('dataDowncast').elementToStructure({
            model: 'videoBlock', view: (modelElement, {writer}) => this._createBlockVideoViewElement(writer)
        });

        editor.conversion.for('editingDowncast').elementToStructure({
            model: 'videoBlock', view: (modelElement, {writer}) => {
                return toWidget(this._createBlockVideoViewElement(writer), writer)
            }
        });
        editor.conversion.for('downcast')
            .add(this._downcastVideoAttribute('videoBlock', 'src'))
            .add(this._downcastVideoAttribute('videoBlock', 'style'))
            .add(this._downcastVideoAttribute('videoBlock', 'controls'))
            .add(this._downcastVideoAttribute('videoBlock'));
    }

    // 创建视频标签
    _createBlockVideoViewElement(writer) {
        return writer.createContainerElement('figure', {
            class: 'video'
        }, [
            writer.createEmptyElement('video'),
            writer.createSlot()
        ]);
    }

    // 设置视频属性
    _downcastVideoAttribute(imageType, attributeKey) {
        const editor = this.editor;
        return dispatcher => {
            dispatcher.on(`attribute:${attributeKey}:${imageType}`, (evt, data, conversionApi) => {
                // console.log(`attribute:${attributeKey}:${imageType}`)
                if (!conversionApi.consumable.consume(data.item, evt.name)) return;
                let element = conversionApi.mapper.toViewElement(data.item);
                for (const {item} of editor.editing.view.createRangeIn(element)) {
                    if (!!item && item.is('element', 'video')) {
                        element = item;
                        break;
                    }
                }
                conversionApi.writer.setAttribute(data.attributeKey, data.attributeNewValue || '', element);
            });
        };
    }
}